package Game;
import java.util.Stack;
import org.newdawn.slick.SlickException;




public class PathMaker{
	
	// The map to create the path upon.
	private Map map;
	
	// A stack storing the order of the path in the map
	private static Stack<Path> pathOrder;

	// The starting position of the path
	private static Path startingPath;
	
	// Indicates a straight vertical path
	private final static int VERT = 0;
	
	// Indicates a straight horisontal path
	private final static int HORI = 1;
	
	// Indicates a straight horizontal path from the east
	private final static int HORIW = 3;
	
	// Indicates a corner from west to south
	private final static int WTOS = 2;
	
	public PathMaker(Map map){
		this.map = map;
		pathOrder = new Stack<Path>();
	}
	
	/**
	 * Create a pre-specified path on the specified map.
	 * @throws SlickException
	 */
	public void makePath() throws SlickException{
		createLineBetween(0, 3, 9, 3, HORI);
		createLineBetween(10, 3, 10, 5, VERT);
		createLineBetween(10, 6, 2, 6, HORIW);
		createLineBetween(1, 6, 1, 12, VERT);
		linkPaths();
	}
	
	/**
	 * Fill a line of tiles in the map with a certain terrain.
	 * 
	 * @param fromX the x position to start from
	 * @param fromY the y position to start from
	 * @param toX the x position to end at
	 * @param toY the y position to end at
	 * @param terrain the terrain type to be added
	 * @throws SlickException 
	 */
	public void createLineBetween(int fromX, int fromY, int toX, int toY, int direction) throws SlickException {
		//TODO : Add something that sets a specific graphic based on direction.
		//TODO : Do we want angle?
		int degrees = 0;
		switch(direction){
			case(HORI): degrees = 180; break;
			case(WTOS): degrees = 225; break;
			case(VERT): degrees = 270; break;
			case(HORIW): degrees = 0; break;
		}
		//If its horisontal
		if(fromX == toX){
			if(toY >= fromY){
				for(int i = fromY; i <= toY; i++){
					Path newPath = new Path(fromX, i, degrees);
					map.addUnit(newPath, fromX, i);
					pathOrder.push(newPath);
				}
			} else {
				for(int i = fromY; i >= toY; i--){
					Path newPath = new Path(fromX, i, degrees);
					map.addUnit(newPath, fromX, i);
					pathOrder.push(newPath);
				}	
			}
		//If its vertical
		} else if (fromY == toY) {
			if(toX >= fromX){
				for(int i = fromX; i <= toX; i++){
					Path newPath = new Path(i, fromY, degrees);
					map.addUnit(newPath, i, fromY);
					pathOrder.push(newPath);
				}
			} else {
				for(int i = fromX; i >= toX; i--){
					Path newPath = new Path(i, fromY, degrees);
					map.addUnit(newPath, i, fromY);
					pathOrder.push(newPath);
				}
			}
		}
	}
	
	/**
	 * Link the path together in the order they
	 * have been added to the map.
	 */
	public void linkPaths(){
		Path path = null;
		Path destination = null;
		while(!(pathOrder.isEmpty())){
			path = pathOrder.pop();
			path.setNextPath(destination);
			destination = path;
		}
		startingPath = path;
	}
	
	/**
	 * Creates the goal of the path.
	 * @param x the x coordinate of the tile
	 * @param y the y coordinate of the tile
	 * @param degrees the angle in which the tile is directed
	 * @throws SlickException
	 */
	public void createGoal(int x, int y, int degrees) throws SlickException{
		Path newPath = new Path(x, y, degrees);
		map.addUnit(newPath, x, y);
		pathOrder.push(newPath);
	}
	
	/**
	 * Return the starting path if one has been created,
	 * else null
	 * @return starting point for the path
	 */
	public Path getStartingPath(){
		return startingPath;
	}

	public void print(){
		Path tempPath = startingPath;
		while(tempPath!= null){
			System.out.println("(" + tempPath.getX() + "," + tempPath.getY() + "," + tempPath.getAngle() + ")");
			tempPath = tempPath.getNext();
		}
	}
}